package action

import (
	"strings"
	"time"

	"gitee.com/sansaniot/ssiot-core/facade/env"
	"gitee.com/sansaniot/ssiot-core/logger"
	"github.com/bytedance/sonic"
	"gorm.io/gorm"

	"ssalarm/common/constant"
	"ssalarm/common/dto"
	"ssalarm/common/utils"
	"ssalarm/internal/alarm/models"
	"ssalarm/internal/alarm/models/query"
	"ssalarm/internal/alarm/service"
)

type Broad struct {
	Orm *gorm.DB
}

func (action *Broad) Execute(topic string, jsonData map[string]interface{}) {
	if topic == constant.DeviceDeleteMsgTopic {
		handleDeviceDelete(action.Orm, jsonData)
	} else if topic == constant.DeviceAddMsgTopic {
		handleDeviceAdd(action.Orm, jsonData)
	}
}

func handleDeviceDelete(db *gorm.DB, jsonData map[string]interface{}) {
	sn, ok := jsonData["sn"]
	if !ok || sn == nil {
		return
	}
	snList := strings.Split(strings.ReplaceAll(sn.(string), " ", ""), ",")
	alarmConfig := &models.SysAlarmConfig{}
	alarmConfig.Orm = db
	if err := alarmConfig.DeleteAlarmConfig(snList); err != nil {
		logger.Error(err)
	}
}

func handleDeviceAdd(db *gorm.DB, jsonData map[string]interface{}) {
	sn, ok := jsonData["sn"]
	if !ok || sn == nil {
		return
	}
	productCode, ok := jsonData["productCode"]
	if !ok || productCode == nil || len(productCode.(string)) == 0 {
		return
	}
	// 添加设备跟随产品告警配置
	alarmConfig := &models.SysAlarmConfig{}
	alarmConfig.Orm = db
	err, productConfigList := alarmConfig.FindAlarmConfig(&query.SysDevAlarmConfigQuery{ProductCode: productCode.(string)})
	if err != nil {
		logger.Error(err)
		return
	}
	if len(productConfigList) == 0 {
		return
	}
	devConfigList := make([]models.SysAlarmConfig, 0)
	now := dto.LocalTime(time.Now())
	for _, v := range productConfigList {
		devConfigList = append(devConfigList, models.SysAlarmConfig{
			DevSn:        sn.(string),
			Key:          v.Key,
			Warning:      v.Warning,
			Enable:       v.Enable,
			ProductCode:  "",
			DevProductId: "",
			CreateTime:   nil,
			UpdateTime:   &now,
		})
	}
	if err = alarmConfig.Upsert(&devConfigList, []string{"dev_sn", "key"}...); err != nil {
		logger.Error(err)
		return
	}
	// 设备告警配置缓存
	for _, v := range devConfigList {
		redisWarn := make([]map[string]interface{}, 0)
		service.GenRedisWarn(&redisWarn, utils.BytesToMapArr(v.Warning))
		bytes, _ := sonic.Marshal(redisWarn)
		redisWarnStr := string(bytes)
		if err = env.Cache.HashSet(constant.AlarmConfigKey+v.DevSn, map[string]interface{}{v.Key: redisWarnStr}); err == nil {
			constant.HasAlarmConfigSn.Store(v.DevSn, v.DevSn)
		}
	}
}
